#import <Flutter/Flutter.h>
#import "WhiteSDK.h"
#import "WhiteRoomConfig.h"
#import "WhiteSdkConfiguration.h"
#import "WhiteSDK+Room.h"
#import "WhiteRoom.h"

@implementation WhiteSdkView : NSObject  {
  WhiteRoom* _room;
  WhiteSDK* _sdk;
  WhiteBoardView* _whiteboardView;
  int64_t _viewId;
  FlutterMethodChannel* _channel;
}

- (instancetype)initWithFrame:(CGRect)frame
               viewIdentifier:(int64_t)viewId
                    arguments:(id _Nullable)args
              binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {

    _viewId = viewId;
    NSString* channelName = [NSString stringWithFormat:@"plugins.netless.link/whiteboard_%lld", viewId];
    _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];

    __weak __typeof__(self) weakSelf = self;
    [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
        [weakSelf onMethodCall:call result:result];
    }];
    WKWebViewConfiguration *webViewConfig = [[WKWebViewConfiguration alloc] init];
    _whiteboardView = [[WhiteBoardView alloc] initWithFrame:frame
        configuration: webViewConfig
    ];
    

    return self;
}

- (UIView*)view {
  return _whiteboardView;
}

- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    if ([[call method] isEqualToString:@"createSdk"]) {
        NSDictionary* arguments = [call arguments];
        NSString *appId = [arguments objectForKey: @"appId"];
        // 4. 初始化 SDK 配置类，根据需求设置配置
        WhiteSdkConfiguration *config = [[WhiteSdkConfiguration alloc] initWithApp:appId];
        // 5. 初始化 WhiteSDK，并传入callback，可以在 Example 中查看 callback 实现
        _sdk = [[WhiteSDK alloc] initWithWhiteBoardView:_whiteboardView config:config commonCallbackDelegate:self];
    }  else if ([[call method] isEqualToString:@"joinRoom"]) {
        NSDictionary* arguments = [call arguments];
        NSString *uuid = [arguments objectForKey: @"uuid"];
        NSString *roomToken = [arguments objectForKey: @"roomToken"];
        WhiteRoomConfig *roomConfig = [[WhiteRoomConfig alloc] initWithUuid:uuid roomToken:roomToken];
        
        
        [_sdk joinRoomWithConfig:roomConfig
                       callbacks:self
               completionHandler:^(BOOL success, WhiteRoom * _Nonnull room, NSError * _Nonnull error) {
            if (success) {
                self->_room = room;
                result(self->_room.observerId);
            } else {
                NSString *message = [error localizedDescription];
                // 错误处理
                result([FlutterError
                    errorWithCode:@"joinRoomError"
                    message: message
                    details:[NSString stringWithFormat:error]
                ]);
            }
        }];
    } else {
        result(FlutterMethodNotImplemented);
    }
}


/** 白板网络连接状态回调事件 */
- (void)firePhaseChanged:(WhiteRoomPhase)phase {

}

/**
 白板中RoomState属性，发生变化时，会触发该回调。
 注意：主动设置的 RoomState，不会触发该回调。
 目前有个别 state 内容，主动调用时，也会触发。
 @param modifyState 发生变化的 RoomState 内容
 */
- (void)fireRoomStateChanged:(WhiteRoomState *)modifyState{
    
}

- (void)fireBeingAbleToCommitChange:(BOOL)isAbleToCommit{
    
}
- (void)fireDisconnectWithError:(NSString *)error{
    
}

/** 用户被远程服务器踢出房间，附带踢出原因 */
- (void)fireKickedWithReason:(NSString *)reason{
    
}

/** 用户错误事件捕获，附带用户 id，以及错误原因 */
- (void)fireCatchErrorWhenAppendFrame:(NSUInteger)userId error:(NSString *)error{
    
}

/**
 白板自定义事件回调，
 自定义事件参考文档，或者 RoomTests 代码
 */
- (void)fireMagixEvent:(WhiteEvent *)event{
    
}



/** 当sdk出现未捕获的全局错误时，会在此处对抛出 NSError 对象 */
- (void)throwError:(NSError *)error {

}


/**
 图片拦截替换回调。
 启用该功能，需要在初始化 SDK 时，配置 WhiteSdkConfiguration enableInterrupterAPI 属性 为 YES；
 初始化后，无法更改。
 启用后，在调用插入图片API/插入scene 时，会回调该 API，允许在实际显示时，替换 url
 在回放中，也会持续调用。
 @param url 原始图片地址
 @return 替换后的图片地址
 */
- (NSString *)urlInterrupter:(NSString *)url {
    return url;
}

/**
 * 动态 ppt 中的音视频媒体，播放通知
 */
- (void)pptMediaPlay {

}

/**
 * 动态 ppt 中的音视频媒体，暂停通知
 */
- (void)pptMediaPause {

}

/**
 * 初始化 SDK 时，会根据传入的 App Identifier 向服务器配置信息（最多尝试三次）
 * 如果失败，SDK 处于不可用状态，调用加入房间/回放房间会处于一直无响应状态，需要开发者重新初始化 SDK。
 * 一般触发情况：
 * 1. 初始化 SDK 时候，网络异常，导致获取配置信息失败；
 * 2. 传入了错误不合法的 App Identifier
 * @since 2.9.13
 */
- (void)sdkSetupFail:(NSError *)error {

}

@end
